#include "Position.h"

template <class T>
inline Position<T>::Position(){
	

	x = y = 0;

}
template <class T>
inline Position<T>::Position(T x, T y){
	

	set(x,y);

}
template <class T>
inline Position<T>::Position(const Position<T>& b){
	

	set(b.x,b.y);

}

template <class T>
inline void Position<T>::set(T x, T y){


	this->x = x;
	this->y = y;

}

template <class T>
inline void Position<T>::round()
{
	x = round(x);
	y = round(y);
}

template <class T>
inline bool Position<T>::operator==(const Position<T>& b) const{


	return (b.x == this->x && b.y == this->y);


}

template <class T>
inline Position<T>& Position<T>::operator=(const Position<T>& b){


	set(b.x,b.y);

	return (*this);

}

template <class T>
inline Position<T> Position<T>::operator+ (const Position<T>& b) const
{
    return Position<T>(
        this->x + b.x,
        this->y + b.y);
}

template <class T>
inline Position<T> Position<T>::operator- (const Position<T>& b) const
{
    return Position<T>(
        this->x - b.x,
        this->y - b.y);
 
}

template <class T>
inline Position<T> Position<T>::operator+ (T fScalar) const
{
    return Position<T>(
        this->x + fScalar,
        this->y + fScalar);


}

template <class T>
inline Position<T> Position<T>::operator- (T fScalar) const
{
	return Position<T>(
    this->x - fScalar,
    this->y - fScalar);
}


template <class T> 
inline Position<T> Position<T>::operator* (T fScalar) const
{
    return Position<T>(
        fScalar*this->x,
        fScalar*this->y);
}

template <class T>
inline Position<T> Position<T>::operator/ (T fScalar) const
{
 
    if (fScalar == 0.0)
    {

        return Position<T>(); 
 
    }
 
    return Position<T>(this->x / fScalar, this->y / fScalar);
}

template <class T> 
inline Position<T> Position<T>::operator- () const
{
    return Position<T>(
        -this->x,
        -this->y);
}

template <class T>
inline T Position<T>::length() const{

	return sqrt(this->x * this->x + this->y * this->y);

}


template <class T>
Position<T> Position<T>::normalizedCopy() const{

	T length = this->length();

	if(length == 0)
		return Position<T>();


	return Position<T>(
		this->x / length,
		this->y / length);

}

template <class T>
void Position<T>::normalize(){

	T length = (*this).length();

	if(length == 0)
		return;

	
	
	this->x /= length;
	this->y /= length;

}

template <class T>
inline T Position<T>::dot(const Position<T>& b) const{


	return (this->x * b.x + this->y * b.y);

}

template <class T>
inline T Position<T>::cross(const Position<T>& b) const{


	return (this->x * b.y - this->y * b.x);

}

template <class T>
T Position<T>::getAngle() const{

	double v = atan2((double)this->y,(double)this->x);

	if(v < 0) v += 2*3.14159;


	v = v * 180 / 3.14159 + 90;
	return  (int)v % 360;

}

template <class T>
T Position<T>::getAngleDif(T angle) const{


	return SubtractAngles(angle,this->getAngle());

}

template <class T>
inline bool Position<T>::inArea(const Position<T>& a, const Position<T>& b) const {

	return (((this->x < a.x) ^ (this->x < b.x)) &&
			((this->x > a.x) ^ (this->x > b.x)) &&
			((this->y < a.y) ^ (this->y < b.y)) &&
			((this->y > a.y) ^ (this->y > b.y)));


}

template <class T>
inline void Position<T>::setToBounds(const Position<T>& a, const Position<T>& b) {

	x = (x > a.x) ? x : a.x;
	y = (y > a.y) ? y : a.y;
	x = (x < b.x) ? x : b.x;
	y = (y < b.y) ? y : b.y;

}


//subtracts angle2 from angle1 and returns the real angular distance between them
template <class T>
T Position<T>::SubtractAngles(T angle1, T angle2) const
{
	T angle = angle1 + 180 - angle2;

	if(angle < 0 || angle > 360)
	{
		angle -= (int)std::floor((double)(angle / 360)) * 360;
	}

	return angle - 180;
}

template <class T>
T Position<T>::round(T a) const{

	T af = std::floor((double)a);
	if(a - af < .5)
		return af;

	return af + 1;

}